#include <QtGui>
#include <QtNetwork>
#include <QDesktopServices>

#include "ftpbrowser.h"
#include "Core.h"

FtpWindow::FtpWindow(QWidget *parent, const Loom& jc) : QDialog(parent),
  mr_jc(jc),
  ftp ( 0)
{
  ftpServerLabel    = new QLabel(QString("Controleur %1 (%2)").arg(jc.Name()).arg(jc.Address().toString()));
  statusLabel       = new QLabel();
  fileList          = new QTreeWidget;
  fileList->setEnabled(false);
  fileList->setRootIsDecorated(false);
  fileList->setHeaderLabels(QStringList() << tr("Nom") << tr("Taille") << tr("Date"));
  fileList->header()->setMinimumSectionSize(300);
  fileList->header()->setStretchLastSection(false);
  removeButton    = new QPushButton(tr("Effacer du controleur"));
  removeButton->setEnabled(false);
  downloadButton    = new QPushButton(tr("Telecharger vers le bureau"));
  downloadButton->setEnabled(false);
  quitButton        = new QPushButton(tr("Fermer"));
  buttonBox         = new QDialogButtonBox;
  buttonBox->addButton(removeButton,   QDialogButtonBox::ActionRole);
  buttonBox->addButton(downloadButton, QDialogButtonBox::ActionRole);
  buttonBox->addButton(quitButton,     QDialogButtonBox::RejectRole);
  progressDialog    = new QProgressDialog(this);

  //connect(fileList,       SIGNAL(itemActivated     (QTreeWidgetItem *, int              )), SLOT(processItem(QTreeWidgetItem *, int)));
  connect(fileList,       SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), SLOT(enableButtons()  ));
  connect(progressDialog, SIGNAL(canceled()                                              ), SLOT(cancelDownload() ));
  connect(downloadButton, SIGNAL(clicked()                                               ), SLOT(downloadFile()   ));
  connect(removeButton,   SIGNAL(clicked()                                               ), SLOT(removeFile()     ));
  connect(quitButton,     SIGNAL(clicked()                                               ), SLOT(close()          ));

  QHBoxLayout *topLayout = new QHBoxLayout;
  topLayout->addWidget(ftpServerLabel);

  QVBoxLayout *mainLayout = new QVBoxLayout;
  mainLayout->addLayout(topLayout);
  mainLayout->addWidget(fileList);
  mainLayout->addWidget(statusLabel);
  mainLayout->addWidget(buttonBox);
  setLayout(mainLayout);

  setWindowTitle(tr("Explorateur du disque JC"));

  connectJC();
}

QSize FtpWindow::sizeHint() const
{
    return QSize(500, 300);
}

FtpWindow::~FtpWindow()
{
  ftp->abort();
  ftp->deleteLater();
  ftp = NULL;
}

void FtpWindow::connectJC()
{
    setCursor(Qt::WaitCursor);
    ftp = new QFtp(this);
    connect(ftp, SIGNAL(commandFinished(int, bool)), this, SLOT(ftpCommandFinished(int, bool)));
    connect(ftp, SIGNAL(listInfo(const QUrlInfo &)), this, SLOT(addToList(const QUrlInfo &)));
    connect(ftp, SIGNAL(dataTransferProgress(qint64, qint64)), this, SLOT(updateDataTransferProgress(qint64, qint64)));

    fileList->clear();
    currentPath.clear();
    isDirectory.clear();

    ftp->connectToHost   (mr_jc.Address().toString());
    ftp->setTransferMode (QFtp::Active);
    ftp->login           (mr_jc.Login(), mr_jc.Password());
    ftp->cd              (mr_jc.DstPath());

    fileList->setEnabled(true);
    //connectButton->setEnabled(false);
    //connectButton->setText(tr("Disconnect"));
    statusLabel->setText("Connexion en cours...");
}

void FtpWindow::removeFile ()
{
  QString msg("Attention, vous allez retirer definitivement ce fichier du disque du controleur.\nDesirez vous valider cette action ?");
  if (QMessageBox::Ok == QMessageBox::question(this, "Effacer un fichier", msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel))
  {
    ftp->remove(fileList->currentItem()->text(0));
  }
}

void FtpWindow::downloadFile()
{
  // remote file:
  QString src = fileList->currentItem()->text(0);
  int totalSz = QString(fileList->currentItem()->text(1)).toInt();

  // Local path
  QString path(QDesktopServices::storageLocation (QDesktopServices::DesktopLocation));
  QString dest(path+QDir::separator()+src);

  if (QFile::exists(dest)) 
  {
    if (QMessageBox::Ok != QMessageBox::question(this, 
      "Transfert FTP", 
      "Un fichier de meme nom existe deja sur le bureau.\nVoulez vous l'ecraser ?", 
      QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel)) 
      return;
  }

  mp_file = new QFile(dest);
  if (!mp_file->open(QIODevice::WriteOnly))
  {
    QMessageBox::warning(this,
      "Transfert FTP", 
      QString("Impossible d'ecrire dans le fichier %1 sur le bureau. Verifez qu'il ne soit pas ouvert par un logiciel").arg(src));
    delete mp_file; mp_file = NULL;
    return;
  }

  ftp->get(src, mp_file, QFtp::Binary);

  progressDialog->setLabelText(tr("\"%1\" en cours de transfert...").arg(src));
  progressDialog->setMaximum(totalSz);
  downloadButton->setEnabled(false);
  removeButton  ->setEnabled(false);
  progressDialog->exec();
}
void FtpWindow::cancelDownload()
{
  ftp->abort();
}
void FtpWindow::ftpCommandFinished(int, bool error)
{
  setCursor(Qt::ArrowCursor);

  if (ftp->currentCommand() == QFtp::ConnectToHost)
  {
    if (error) 
    {
      QMessageBox::information(this, "Connexion au controleur", "Impossible de se connecter au controleur.\nVerifiez votre cablage et l'etat du controleur\n(eteint ? Son adresse IP sur Loomfeed et sur le JC...)");
      return;
    }

    statusLabel->setText("Acces authorise");
    fileList->setFocus();
    downloadButton->setDefault(true);
    return;
  }
  if (ftp->currentCommand() == QFtp::Login)
  {
    if (error)
    {
      statusLabel->setText("Identification refusee");
    }
  }
  if (ftp->currentCommand() == QFtp::Cd)
  {
    if (error)
    {
      statusLabel->setText("Navigation dans les repertoires impossible");
    }
    else
    {
      ftp->list();
      statusLabel->setText("Recuperation de la liste des fichiers...");
    }
  }
  if (ftp->currentCommand() == QFtp::Remove)
  {
    if (error)
    {
      statusLabel->setText("Effacement du fichier refuse !");
    }
    else
    {
      fileList->clear();
      isDirectory.clear();
      ftp->list();
      statusLabel->setText("Recuperation de la liste des fichiers...");
    }
  }
  else if (ftp->currentCommand() == QFtp::List)
  {
    statusLabel->setText(error ? "Erreur..." : "Ok");
    if (isDirectory.isEmpty() || error) 
    {
      fileList->clear();
      fileList->addTopLevelItem(new QTreeWidgetItem(QStringList() << tr("<Vide>")));
      fileList->setEnabled(false);
    }
  }
  if (ftp->currentCommand() == QFtp::Get)
  {
    if (error)
    {
      statusLabel->setText(QString("Transfert annule de \"%1\".").arg(QFileInfo(mp_file->fileName()).fileName()));
      mp_file->close();
      mp_file->remove();
    } else {
      statusLabel->setText(QString("Transfert termine de \"%1\".").arg(QFileInfo(mp_file->fileName()).fileName()));
      mp_file->close();
    }
    delete mp_file; mp_file = NULL;
    enableButtons();
    progressDialog->hide();
  } 
}

void FtpWindow::addToList(const QUrlInfo &urlInfo)
{
  if (urlInfo.name() == "." || urlInfo.name() == "..") return;

  QTreeWidgetItem *item = new QTreeWidgetItem;
  item->setText(0, urlInfo.name());
  item->setText(1, QString::number(urlInfo.size()));
  item->setText(2, urlInfo.lastModified().toString("MMM dd yyyy"));

  QPixmap pixmap(urlInfo.isDir() ? ":/dir.png" : ":/file.png");
  item->setIcon(0, pixmap);

  isDirectory[urlInfo.name()] = urlInfo.isDir();
  fileList->addTopLevelItem(item);
  if (!fileList->currentItem()) 
  {
    fileList->setCurrentItem(fileList->topLevelItem(0));
    fileList->setEnabled(true);
  }
}
  /*
void FtpWindow::processItem(QTreeWidgetItem *item, int )
{
    QString name = item->text(0);
    if (isDirectory.value(name)) 
    {
        fileList->clear();
        isDirectory.clear();
        currentPath += "/" + name;
        ftp->cd(name);
        ftp->list();
        setCursor(Qt::WaitCursor);
        return;
    }
}

void FtpWindow::cdToParent()
{
    setCursor(Qt::WaitCursor);
    fileList->clear();
    isDirectory.clear();
    currentPath = currentPath.left(currentPath.lastIndexOf('/'));
    if (currentPath.isEmpty()) {
        cdToParentButton->setEnabled(false);
        ftp->cd("/");
    } else {
        ftp->cd(currentPath);
    }
    ftp->list();
}
*/

void FtpWindow::updateDataTransferProgress(qint64 readBytes, qint64 totalBytes)
{
  Q_UNUSED(totalBytes); // BTW it is -1
  progressDialog->setValue(readBytes);
}

void FtpWindow::enableButtons()
{
  QTreeWidgetItem *current = fileList->currentItem();
  if (current) 
  {
    QString currentFile = current->text(0);
    downloadButton->setEnabled(!isDirectory.value(currentFile));
    removeButton  ->setEnabled(!isDirectory.value(currentFile));
  } 
  else 
  {
    downloadButton->setEnabled(false);
    removeButton  ->setEnabled(false);
  }
}
